from django.shortcuts import render
from rest_framework import mixins
from rest_framework.viewsets import ViewSet, GenericViewSet
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import serializers
from django.contrib.auth import authenticate
from rest_framework_jwt.settings import api_settings
from django.contrib.auth.hashers import check_password
from django.contrib.auth import get_user_model
from rest_framework import status
from users.models import CaptchaReg
from utils.my_mail import my_send_mail
from .tasks import queue_send_mail

User = get_user_model()

from .serializers import UserUserNameLoginSerializer, UserEmailLoginSerializer, UserInfoSerializer, CaptchaRegSerializer

# Create your views here.


"""
1.接收用户的请求, username | password
2.我们收到请求之后, 验证码username | password 是否成功
3.如果成功的话,我们就去返回一个json web token
"""


class UserUserNameLoginView(APIView):

    def post(self, request):
        data = UserUserNameLoginSerializer(data=request.POST)

        if not data.is_valid():
            raise serializers.ValidationError(data.errors)
        vali_data = data.validated_data
        user = authenticate(**vali_data)
        if not user:
            raise serializers.ValidationError({'error': '用户名或者密码错误'})

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return Response({"token": token})


"""
1.接收用户的请求, email | password
2.我们收到请求之后, email | password 是否成功
3.如果成功的话,我们就去返回一个json web token
"""


class UserEmailLoginView(APIView):

    def post(self, request):
        data = UserEmailLoginSerializer(data=request.POST)

        if not data.is_valid():
            err = data.errors
            raise serializers.ValidationError(err)
        vali_data = data.validated_data

        try:
            user = User.objects.filter(email=vali_data['email']).order_by('-id')[0]
        except Exception:
            raise serializers.ValidationError({'error': '没有这个用户'})
        enpassword = user.password
        res = check_password(vali_data['password'], encoded=enpassword)

        # 也可以用这个 不过会多一次数据库操作
        # user2 = authenticate(username=user.username,password=vali_data['password'])
        if not res:
            raise serializers.ValidationError({'error': '密码错误'})

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return Response({"token": token})


class UserInfoViewSet(mixins.CreateModelMixin, GenericViewSet):
    serializer_class = UserInfoSerializer
    queryset = User.objects.all()

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        return Response({'token': token}, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        return serializer.save()


"""
简介:
    我们需要发送邮箱验证码,用户接受到邮箱验证码之后把验证码密码邮箱账户一并
    发送到后台注册
1.注册的时候需要填写邮箱,我们后台会验证邮箱是否重复
2.如果邮箱不重复，发送验证码
3.用户自行去接收验证码
4.用户提交验证码 邮箱 密码 用户名
5.后台去验证邮箱验证码是否正确,如果匹配才会创建用户
"""


class RegisterCaptchaViewSet(mixins.CreateModelMixin, GenericViewSet):
    queryset = CaptchaRegSerializer.Meta.model.objects.all()
    serializer_class = CaptchaRegSerializer

    def perform_create(self, serializer):
        data = serializer.validated_data
        serializer.save()
        content = "你的注册验证码为{}".format(data['captcha'])
        #这一步程序是会卡住 或者说这一步程序是相当耗时的
        #所以说我们要把这一步移开
        # notice('my_send_mail')
        #res = my_send_mail('注册验证码', content, data['email'])
        queue_send_mail.delay('注册验证码', content, data['email'])
